package com.market.manager;

import java.util.List;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.market.domain.Picture;
import com.market.domain.Product;
import com.market.domain.PurchaseSchedule;

public interface ProductManager extends GenericManager<Product, Long> {
	
	/**
	 * This method load all products that are organic
	 * 
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Product> fetchAllOrganicProducts();
	
	/**
	 * This method load all products that the type is TOFU
	 * 
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Product> fetchAllTofuProducts();

	/**
	 * This method load all products that inventory > 0
	 * 
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Product> fetchAllHaveInventory();
	
	
	/**
	 * This method load all products that inventory > 0 and is not fresh food
	 * 
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Product> fetchAllNotFreshHaveInventory();
	
	/**
	 * This method load all products that related to active weeklys.
	 * 
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Product> fetchActiveWeeklyProducts();

	/**
	 * This load all pictures are associated with this product
	 * 
	 * @param user
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<Picture> fetchPictures(Product product);

	/**
	 * This load all purchase schedule are associated with this product
	 * 
	 * @param user
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public List<PurchaseSchedule> fetchPurchaseSchedules(Product product);

	/**
	 * This method load inventory for specific product;
	 * 
	 * @param productID
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
	public Integer fetchInventory(Long productID);

	/**
	 * Update specified product's inventory to new value;
	 * 
	 * @param productId
	 * @param newInventory
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = RuntimeException.class)
	public void storeInventory(Product product);

	/**
	 * Update specific product's price information, include price, specialPrice, unitPrice, chineseUnitPrice, frenchUnitPrice.
	 * 
	 * unitPrice(eg. 0.85/lb) 
	 * 
	 * @param product
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = RuntimeException.class)
	public void storePriceInfo(Product product);
}
